Skip to content

Conversation

@pcanal
Copy link
Member

@pcanal pcanal commented Feb 8, 2026

References for class names and objects are stored in 64bits whenever they are
located past 1GB.  This is the 'only' option as there are no control bits left
to distinguish between a 32bits and a 64bits reference.

Reference in the longRange section (>1GB) are now tagged so that we can differentiate nullptr
(stored as only 32 bits) from short reference stored in the longRange section (i.e. those are stored
in 64 bits but have only zeros in the high bit).

For now, the testing of the long range references is disabled.
References for class names and objects are stored in 64bits whenever they are
located past 1GB.  This is the 'only' option as there are no control bits left
to distinguish between a 32bits and a 64bits reference.
Reference in the longRange section (>1GB) are now tagged so that we can differentiate nullptr
(stored as only 32 bits) from short reference stored in the longRange section (i.e. those are stored
in 64 bits but have only zeros in the high bit).
@pcanal pcanal requested a review from jblomer February 8, 2026 17:08
@pcanal pcanal self-assigned this Feb 8, 2026
@pcanal pcanal requested review from dpiparo and linev as code owners February 8, 2026 17:08
@pcanal pcanal changed the title io: Correct handling of byte count pos in TBufferFile::ReadObjectAny io: Add support for long range references in TBufferFile Feb 8, 2026
@github-actions
Copy link

github-actions bot commented Feb 8, 2026

Test Results

    22 files  +    1      22 suites  +1   3d 17h 9m 22s ⏱️ + 4h 45m 44s
 3 777 tests ±    0   3 728 ✅ ±    0    1 💤 ±0   48 ❌ ± 0 
76 033 runs  +3 724  74 848 ✅ +3 679  254 💤  - 1  931 ❌ +46 

For more details on these failures, see this check.

Results for commit 52b3714. ± Comparison against base commit 588b29e.

virtual void PushDataCache(TVirtualArray *);

virtual TClass *ReadClass(const TClass *cl = nullptr, UInt_t *objTag = nullptr) = 0;
virtual TClass *ReadClass(const TClass *cl = nullptr, ULong64_t *objTag = nullptr) = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could keep the old signature, forward to the new one and throw if the returned objTag is too large.

@@ -1375,7 +1375,7 @@ TString *TString::ReadString(TBuffer &b, const TClass *clReq)
// Before reading object save start position
UInt_t startpos = UInt_t(b.Length());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not subject to this PR but should also be 64bit. Same issue for the write counterpart.

@@ -47,7 +47,7 @@ TArray *TArray::ReadArray(TBuffer &b, const TClass *clReq)
// Before reading object save start position
UInt_t startpos = UInt_t(b.Length());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be 64bit. Same issue for the write counterpart.

@@ -105,7 +105,7 @@ void TConvertClonesArrayToProxy::operator()(TBuffer &b, void *pmember, Int_t siz
UInt_t startpos = b.Length();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

64bit? To be checked for writing.


constexpr ULong64_t kMaxLongRange = 0x0FFFFFFFFFFFFFFE; // We reserve the 4 highest bits for flags, currently only 2 are in use.
constexpr ULong64_t kLongRangeClassMask = 0x8000000000000000; // OR the class index with this
// constexpr ULong64_t kLongRangeByteCountMask = 0x4000000000000000; // OR the byte count with this
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be useful to add a comment why this is commented. Because it conflicts with the regular kByteCountMask?

// This is needed so that the reader can distinguish between references,
// bytecounts, and new class definitions.
ULong64_t objIdx = static_cast<ULong64_t>(idx);
// FIXME: verify that objIdx is guaranteed to fit in 60-bits, i.e. objIdx <= kMaxLongRange
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment can be removed, I think

// This is needed so that the reader can distinguish between references,
// bytecounts, and new class definitions.
ULong64_t clIdx = static_cast<ULong64_t>(idx);
// FIXME: verify that clIdx is guaranteed to fit in 60-bits, i.e. clIdx <= kMaxLongRange
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be removed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants